package com.eshop.modules.activity.service.impl;

import java.lang.invoke.SerializedLambda;
import java.io.IOException;
import com.eshop.utils.FileUtil;
import java.util.ArrayList;
import javax.servlet.http.HttpServletResponse;
import com.eshop.common.utils.QueryHelpPlus;
import java.util.Iterator;
import com.eshop.modules.activity.service.dto.StoreBargainDto;
import java.util.LinkedHashMap;
import com.github.pagehelper.PageInfo;
import java.util.Map;
import org.springframework.data.domain.Pageable;
import com.eshop.modules.activity.service.dto.StoreBargainQueryCriteria;
import com.eshop.modules.order.domain.StoreOrder;
import com.eshop.enums.OrderInfoEnum;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import java.util.List;
import com.eshop.modules.user.vo.UserQueryVo;
import com.eshop.modules.activity.vo.StoreBargainQueryVo;
import com.eshop.enums.ShopCommonEnum;
import java.util.Date;
import com.eshop.modules.activity.vo.BargainVo;
import com.eshop.modules.user.domain.ShopUser;
import com.eshop.modules.activity.vo.BargainCountVo;
import com.eshop.modules.activity.vo.TopCountVo;
import com.eshop.modules.activity.domain.StoreBargainUser;
import java.math.BigDecimal;
import com.eshop.modules.activity.domain.StoreBargainUserHelp;
import com.eshop.utils.OrderUtil;
import cn.hutool.core.util.NumberUtil;
import java.io.Serializable;
import com.eshop.api.EshopException;
import com.eshop.modules.activity.service.StoreBargainUserHelpService;
import com.eshop.modules.order.service.StoreOrderService;
import com.eshop.modules.activity.service.StoreBargainUserService;
import org.springframework.beans.factory.annotation.Autowired;
import com.eshop.dozer.service.IGenerator;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.stereotype.Service;
import com.eshop.modules.activity.service.StoreBargainService;
import com.eshop.modules.activity.domain.StoreBargain;
import com.eshop.modules.activity.service.mapper.StoreBargainMapper;
import com.eshop.common.service.impl.BaseServiceImpl;

@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = { Exception.class })
public class StoreBargainServiceImpl extends BaseServiceImpl<StoreBargainMapper, StoreBargain> implements StoreBargainService
{
    @Autowired
    private IGenerator generator;
    @Autowired
    private StoreBargainMapper storeBargainMapper;
    @Autowired
    private StoreBargainUserService storeBargainUserService;
    @Autowired
    private StoreOrderService storeOrderService;
    @Autowired
    private StoreBargainUserHelpService storeBargainUserHelpService;
    
    public void incStockDecSales(final int num, final Long bargainId) {
        this.storeBargainMapper.incStockDecSales(num, bargainId);
    }
    
    public void decStockIncSales(final int num, final Long bargainId) {
        final int res = this.storeBargainMapper.decStockIncSales(num, bargainId);
        if (res == 0) {
            throw new EshopException("砍价产品库存不足");
        }
    }
    
    public void doHelp(final Long bargainId, final Long bargainUserUid, final Long uid) {
        final StoreBargainUser storeBargainUser = this.storeBargainUserService.getBargainUserInfo(bargainId, bargainUserUid);
        final StoreBargain storeBargain = (StoreBargain)this.getById((Serializable)bargainId);
        final double coverPrice = NumberUtil.sub((Number)storeBargainUser.getBargainPrice(), (Number)storeBargainUser.getBargainPriceMin()).doubleValue();
        double random = 0.0;
        if (coverPrice > 0.0) {
            final double surplusPrice = NumberUtil.sub((Number)coverPrice, (Number)storeBargainUser.getPrice()).doubleValue();
            if (surplusPrice == 0.0) {
                return;
            }
            random = OrderUtil.randomNumber(storeBargain.getBargainMinPrice().doubleValue(), storeBargain.getBargainMaxPrice().doubleValue());
            if (random > surplusPrice) {
                random = surplusPrice;
            }
        }
        final StoreBargainUserHelp storeBargainUserHelp = StoreBargainUserHelp.builder().uid(uid).bargainId(bargainId).bargainUserId(storeBargainUser.getId()).price(BigDecimal.valueOf(random)).build();
        this.storeBargainUserHelpService.save(storeBargainUserHelp);
        final double totalPrice = NumberUtil.add(storeBargainUser.getPrice().doubleValue(), random);
        final StoreBargainUser bargainUser = StoreBargainUser.builder().id(storeBargainUser.getId()).price(BigDecimal.valueOf(totalPrice)).build();
        this.storeBargainUserService.updateById(bargainUser);
    }
    
    public TopCountVo topCount(final Long bargainId) {
        if (bargainId != null) {
            this.addBargainShare(bargainId);
        }
        return TopCountVo.builder().lookCount(this.storeBargainMapper.lookCount()).shareCount(this.storeBargainMapper.shareCount()).userCount(this.storeBargainUserService.count()).build();
    }
    
    public BargainCountVo helpCount(final Long bargainId, final Long uid, final Long myUid) {
        final StoreBargainUser storeBargainUser = this.storeBargainUserService.getBargainUserInfo(bargainId, uid);
        boolean userBargainStatus = true;
        if (storeBargainUser == null) {
            return BargainCountVo.builder().count(0).alreadyPrice(0.0).status(0).pricePercent(0).price(0.0).userBargainStatus(userBargainStatus).build();
        }
        final int helpCount = (((this.storeBargainUserHelpService.lambdaQuery().eq(StoreBargainUserHelp::getBargainUserId, storeBargainUser.getId())).eq(StoreBargainUserHelp::getBargainId, bargainId)).eq(StoreBargainUserHelp::getUid, myUid)).count();
        if (helpCount > 0) {
            userBargainStatus = false;
        }
        final int count = this.storeBargainUserHelpService.getBargainUserHelpPeopleCount(bargainId, storeBargainUser.getId());
        final double diffPrice = NumberUtil.sub((Number)storeBargainUser.getBargainPrice(), (Number)storeBargainUser.getBargainPriceMin()).doubleValue();
        int pricePercent = 0;
        if (diffPrice <= 0.0) {
            pricePercent = 100;
        }
        else {
            pricePercent = NumberUtil.round(NumberUtil.mul((Number)NumberUtil.div((Number)storeBargainUser.getPrice(), (Number)diffPrice), (Number)100), 0).intValue();
        }
        final double surplusPrice = NumberUtil.sub((Number)diffPrice, (Number)storeBargainUser.getPrice()).doubleValue();
        return BargainCountVo.builder().count(count).alreadyPrice(storeBargainUser.getPrice().doubleValue()).status(storeBargainUser.getStatus()).pricePercent(pricePercent).price(surplusPrice).userBargainStatus(userBargainStatus).build();
    }
    
    public BargainVo getDetail(final Long id, final ShopUser shopUser) {
        final Date now = new Date();
        final StoreBargain storeBargain = ((((this.lambdaQuery().eq(StoreBargain::getId, id)).eq(StoreBargain::getStatus, ShopCommonEnum.IS_STATUS_1.getValue())).le(StoreBargain::getStartTime, now)).ge(StoreBargain::getStopTime, now)).one();
        if (storeBargain == null) {
            throw new EshopException("砍价已结束");
        }
        this.addBargainLook(id);
        final StoreBargainQueryVo storeBargainQueryVo = (StoreBargainQueryVo)this.generator.convert(storeBargain, (Class)StoreBargainQueryVo.class);
        return BargainVo.builder().bargain(storeBargainQueryVo).userInfo((UserQueryVo)this.generator.convert(shopUser, (Class)UserQueryVo.class)).bargainSumCount(this.getBargainPayCount(id)).build();
    }
    
    public List<StoreBargainQueryVo> getList(final int page, final int limit) {
        final Page<StoreBargain> pageModel = (Page<StoreBargain>)new Page((long)page, (long)limit);
        final LambdaQueryWrapper<StoreBargain> wrapper = (LambdaQueryWrapper<StoreBargain>)new LambdaQueryWrapper();
        final Date nowTime = new Date();
        ((wrapper.eq(StoreBargain::getStatus, ShopCommonEnum.IS_STATUS_1.getValue())).lt(StoreBargain::getStartTime, nowTime)).gt(StoreBargain::getStopTime, nowTime);
        final List<StoreBargainQueryVo> storeBargainQueryVos = (List<StoreBargainQueryVo>)this.generator.convert(((Page)this.storeBargainMapper.selectPage((IPage)pageModel, (Wrapper)wrapper)).getRecords(), (Class)StoreBargainQueryVo.class);
        storeBargainQueryVos.forEach(item -> item.setPeople(this.storeBargainUserService.getBargainUserCount(item.getId(), OrderInfoEnum.BARGAIN_STATUS_1.getValue())));
        return storeBargainQueryVos;
    }
    
    private void addBargainShare(final Long id) {
        this.storeBargainMapper.addBargainShare(id);
    }
    
    private void addBargainLook(final Long id) {
        this.storeBargainMapper.addBargainLook(id);
    }
    
    private int getBargainPayCount(final Long bargainId) {
        return (((this.storeOrderService.lambdaQuery().eq(StoreOrder::getBargainId, bargainId)).eq(StoreOrder::getPaid, OrderInfoEnum.PAY_STATUS_1.getValue())).eq(StoreOrder::getRefundStatus, OrderInfoEnum.REFUND_STATUS_0.getValue())).count();
    }
    
    public Map<String, Object> queryAll(final StoreBargainQueryCriteria criteria, final Pageable pageable) {
        this.getPage(pageable);
        final PageInfo<StoreBargain> page = (PageInfo<StoreBargain>)new PageInfo((List)this.queryAll(criteria));
        final Map<String, Object> map = new LinkedHashMap<String, Object>(2);
        final List<StoreBargainDto> storeBargainDtoList = (List<StoreBargainDto>)this.generator.convert(page.getList(), (Class)StoreBargainDto.class);
        for (final StoreBargainDto storeBargainDto : storeBargainDtoList) {
            final String statusStr = OrderUtil.checkActivityStatus(storeBargainDto.getStartTime(), storeBargainDto.getStopTime(), storeBargainDto.getStatus());
            storeBargainDto.setStatusStr(statusStr);
        }
        map.put("content", storeBargainDtoList);
        map.put("totalElements", page.getTotal());
        return map;
    }
    
    public List<StoreBargain> queryAll(final StoreBargainQueryCriteria criteria) {
        return (List<StoreBargain>)((StoreBargainMapper)this.baseMapper).selectList((Wrapper)QueryHelpPlus.getPredicate(StoreBargain.class, criteria));
    }
    
    public void download(final List<StoreBargainDto> all, final HttpServletResponse response) throws IOException {
        final List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        for (final StoreBargainDto yxStoreBargain : all) {
            final Map<String, Object> map = new LinkedHashMap<String, Object>();
            map.put("关联产品ID", yxStoreBargain.getProductId());
            map.put("砍价活动名称", yxStoreBargain.getTitle());
            map.put("砍价活动图片", yxStoreBargain.getImage());
            map.put("单位名称", yxStoreBargain.getUnitName());
            map.put("库存", yxStoreBargain.getStock());
            map.put("销量", yxStoreBargain.getSales());
            map.put("砍价产品轮播图", yxStoreBargain.getImages());
            map.put("砍价开启时间", yxStoreBargain.getStartTime());
            map.put("砍价结束时间", yxStoreBargain.getStopTime());
            map.put("砍价产品名称", yxStoreBargain.getStoreName());
            map.put("砍价金额", yxStoreBargain.getPrice());
            map.put("砍价商品最低价", yxStoreBargain.getMinPrice());
            map.put("每次购买的砍价产品数量", yxStoreBargain.getNum());
            map.put("用户每次砍价的最大金额", yxStoreBargain.getBargainMaxPrice());
            map.put("用户每次砍价的最小金额", yxStoreBargain.getBargainMinPrice());
            map.put("用户每次砍价的次数", yxStoreBargain.getBargainNum());
            map.put("砍价状态 0(到砍价时间不自动开启)  1(到砍价时间自动开启时间)", yxStoreBargain.getStatus());
            map.put("砍价详情", yxStoreBargain.getDescription());
            map.put("反多少积分", yxStoreBargain.getGiveIntegral());
            map.put("砍价活动简介", yxStoreBargain.getInfo());
            map.put("成本价", yxStoreBargain.getCost());
            map.put("排序", yxStoreBargain.getSort());
            map.put("是否推荐0不推荐1推荐", yxStoreBargain.getIsHot());
            map.put("是否包邮 0不包邮 1包邮", yxStoreBargain.getIsPostage());
            map.put("邮费", yxStoreBargain.getPostage());
            map.put("砍价规则", yxStoreBargain.getRule());
            map.put("砍价产品浏览量", yxStoreBargain.getLook());
            map.put("砍价产品分享量", yxStoreBargain.getShare());
            list.add(map);
        }
        FileUtil.downloadExcel((List)list, response);
    }
    
    public void deleteBargainImg(final String name) {
        ((StoreBargainMapper)this.baseMapper).deleteBargainImg(name);
    }
}
